from contextlib import contextmanager

from sqlalchemy import text, func

from . import db_session

# class SQLAlchemy(object):
#     """ 创建与数据库的会话, session在刚被创建的时候，还没有和任何model object 绑定，
#             可认为是无状态的, session 接受到query查询语句, 执行的结果或保持或者关联到session中
#             在实际操作数据库的时候会开启database transaction
#             假设没有修改autocommit的默认值(False), 那么，database transaction 一直会保持，
#             只有等到session发生roll back、committed、或者close的时候才结束，一般建议，当database
#             transaction结束的时候，同时close session, 以保证，每次发起请求，都会创建一个新的session
#             特别是对web应用来说，发起一个请求，若请求使用到Session访问数据库，则创建session，处理完这个请求后，关闭session"""
#     def __init__(self, session_options):
#         self.session = self.create_scoped_session(session_options)
#
#     @staticmethod
#     def create_scoped_session(session_options):
#         return scoped_session(session_options)
#
#
# db = SQLAlchemy(Session)


class DbHandler:
    def __init__(self, db_session):
        self._session = db_session
    
    @contextmanager
    def session_maker(self):
        try:
            yield self._session
        except Exception as e:
            self._session.rollback()
            raise e
        finally:
            self._session.remove()

    def add(self, model_cls, **kwargs):
        with self.session_maker() as _session:
            try:
                model_instance = model_cls(**kwargs)
                print("3333333333", model_instance)
                _session.add(model_instance)
                _session.commit()
                return True
            except Exception as e:
                print(e)
                _session.rollback()
                return False

    def update(self, model_cls, **kwargs):
        with self.session_maker() as _session:
            try:
                _session.query(model_cls).where().update()
                _session.commit()
            except Exception as e:
                _session.rollback()
                return -1
    
    def delete(self, model_cls, **kwargs):
        with self.session_maker() as _session:
            try:
                _session.query(model_cls).where().delete()
                _session.commit()
            except Exception as e:
                _session.rollback()
                return -1

    def search(self, model_cls, filter_str, flag=False, sort_mode="-id",
               page_num=1, page_size=20):
        with self.session_maker() as _session:
            try:
                if not flag:
                    results = _session.query(model_cls).filter(text(
                        filter_str)).order_by(text(sort_mode)).limit(
                        page_size).offset((page_num - 1) * page_size).all()
                    res_len = _session.query(func.count(model_cls.id)).filter(
                        text(filter_str)).scalar()
            except Exception as e:
                return [], -1
            return results, res_len


session = DbHandler(db_session)
# def session_init(fn):
#     @wraps(fn)
#     def wrapper(*args, **kwargs):
#         with session_maker() as session:
#             resource = GlobalResource()
#             if not getattr(resource, "session", None):
#                 resource.session = session
#             fn(*args, **kwargs)
#     return wrapper()


# def session_manage(fn):
#     @wraps(fn)
#     def inner(*args, **kwargs):
#         session = scoped_session(db_session)
#         kwargs.update(session=session)
#         ans = fn(*args, **kwargs)
#         # 关闭会话
#         return ans
#     return inner